//
//  NSDate+TYCompare.m
//  TYFoundation
//
//  Created by 郭艺伟 on 2019/2/28.
//

#import "NSDate+TYCompare.h"
#import "NSDate+TYCreated.h"

#define D_MINUTE    60
#define D_HOUR        3600
#define D_DAY        86400
#define D_WEEK        604800
#define D_YEAR        31556926

static const unsigned componentFlags = (NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekOfMonth |  NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal);


@implementation NSDate (TYCompare)

- (BOOL)ty_isEqualToDateIgnoringTime:(NSDate *)aDate {
    NSDateComponents *components1 = [[NSDate ty_currentCalendar] components:componentFlags fromDate:self];
    NSDateComponents *components2 = [[NSDate ty_currentCalendar] components:componentFlags fromDate:aDate];
    return ((components1.year == components2.year) &&
            (components1.month == components2.month) &&
            (components1.day == components2.day));
}

- (BOOL)ty_isToday {
    return [self ty_isEqualToDateIgnoringTime:[NSDate date]];
}

- (BOOL)ty_isTomorrow {
    return [self ty_isEqualToDateIgnoringTime:[NSDate ty_dateTomorrow]];
}

- (BOOL)ty_isYesterday {
    return [self ty_isEqualToDateIgnoringTime:[NSDate ty_dateYesterday]];
}

- (BOOL)ty_isSameWeekAsDate:(NSDate *)aDate {
    NSDateComponents *components1 = [[NSDate ty_currentCalendar] components:componentFlags fromDate:self];
    NSDateComponents *components2 = [[NSDate ty_currentCalendar] components:componentFlags fromDate:aDate];
    
    // Must be same week. 12/31 and 1/1 will both be week "1" if they are in the same week
    if (components1.weekOfMonth != components2.weekOfMonth) {
        return NO;
    }
    
    // Must have a time interval under 1 week.
    return (ABS([self timeIntervalSinceDate:aDate]) < (NSTimeInterval)D_WEEK);
}

- (BOOL)ty_isThisWeek {
    return [self ty_isSameWeekAsDate:[NSDate date]];
}

- (BOOL)ty_isNextWeek {
    NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_WEEK;
    NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
    return [self ty_isSameWeekAsDate:newDate];
}

- (BOOL)ty_isLastWeek {
    NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] - D_WEEK;
    NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
    return [self ty_isSameWeekAsDate:newDate];
}

- (BOOL)ty_isSameMonthAsDate:(NSDate *)aDate {
    NSDateComponents *components1 = [[NSDate ty_currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth fromDate:self];
    NSDateComponents *components2 = [[NSDate ty_currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth fromDate:aDate];
    return ((components1.month == components2.month) &&
            (components1.year == components2.year));
}

- (BOOL)ty_isThisMonth {
    return [self ty_isSameMonthAsDate:[NSDate date]];
}

- (BOOL)ty_isLastMonth {
    return [self ty_isSameMonthAsDate:[[NSDate date] ty_dateBySubtractingMonths:1]];
}

- (BOOL)ty_isNextMonth {
    return [self ty_isSameMonthAsDate:[[NSDate date] ty_dateByAddingMonths:1]];
}

- (BOOL)ty_isSameYearAsDate:(NSDate *)aDate {
    NSDateComponents *components1 = [[NSDate ty_currentCalendar] components:NSCalendarUnitYear fromDate:self];
    NSDateComponents *components2 = [[NSDate ty_currentCalendar] components:NSCalendarUnitYear fromDate:aDate];
    return (components1.year == components2.year);
}

- (BOOL)ty_isThisYear {
    return [self ty_isSameYearAsDate:[NSDate date]];
}

- (BOOL)ty_isNextYear {
    NSDateComponents *components1 = [[NSDate ty_currentCalendar] components:NSCalendarUnitYear fromDate:self];
    NSDateComponents *components2 = [[NSDate ty_currentCalendar] components:NSCalendarUnitYear fromDate:[NSDate date]];
    
    return (components1.year == (components2.year + 1));
}

- (BOOL)ty_isLastYear {
    NSDateComponents *components1 = [[NSDate ty_currentCalendar] components:NSCalendarUnitYear fromDate:self];
    NSDateComponents *components2 = [[NSDate ty_currentCalendar] components:NSCalendarUnitYear fromDate:[NSDate date]];
    
    return (components1.year == (components2.year - 1));
}

- (BOOL)ty_isEarlierThanDate:(NSDate *)aDate {
    return ([self compare:aDate] == NSOrderedAscending);
}

- (BOOL)ty_isLaterThanDate:(NSDate *)aDate {
    return ([self compare:aDate] == NSOrderedDescending);
}

#pragma mark - private
- (NSDate *)ty_dateByAddingMonths:(NSInteger)dMonths {
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    [dateComponents setMonth:dMonths];
    NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0];
    return newDate;
}

- (NSDate *)ty_dateBySubtractingMonths:(NSInteger)dMonths {
    return [self ty_dateByAddingMonths:-dMonths];
}

@end
